// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

#ifndef MANIFEST_VERIFICATION_H_
#define MANIFEST_VERIFICATION_H_

#include <stdint.h>
#include <stdbool.h>
#include "status/rot_status.h"
#include "common/signature_verification.h"
#include "pfm/pfm_observer.h"
#include "cfm/cfm_observer.h"
#include "pcd/pcd_observer.h"
#include "firmware/firmware_update_observer.h"
#include "crypto/rsa.h"
#include "crypto/hash.h"
#include "keystore/keystore.h"
#include "platform.h"


/**
 * Public key used for manifest verification.
 */
#pragma pack(push,1)
struct manifest_verification_key {
	uint32_t id;							/**< ID of the key for revocation. */
	struct rsa_public_key key;				/**< The public key. */
	uint8_t signature[RSA_MAX_KEY_LENGTH];	/**< Signature using the root key of the key data. */
};
#pragma pack(pop)

/**
 * Handler for verification of firmware manifests.  As part of verification, the key used to
 * verify the manifests is maintained and revocation operations are performed.
 */
struct manifest_verification {
	struct signature_verification base_verify;				/**< Base verification instance. */
	struct pfm_observer base_observer;						/**< Base manifest observer instance. */
	struct firmware_update_observer base_update;			/**< Base update observer instance. */
	const struct manifest_verification_key *default_key;	/**< Default key for verification. */
	struct manifest_verification_key *stored_key;			/**< Verification key from the keystore. */
	struct rsa_engine *rsa;									/**< RSA engine for signature verification. */
	struct hash_engine *hash;								/**< Hash engine for manifest validation. */
	struct keystore *keystore;								/**< Storage for the verification key. */
	int key_id;												/**< ID of the key in the keystore. */
	bool save_failed;										/**< Flag indicating if the key was not saved. */
	platform_mutex lock;									/**< Synchronization for key operations. */
};


int manifest_verification_init (struct manifest_verification *verification,
	struct hash_engine *hash, struct rsa_engine *rsa, const struct rsa_public_key *root_key,
	const struct manifest_verification_key *manifest_key, struct keystore *manifest_keystore,
	int key_id);
void manifest_verification_release (struct manifest_verification *verification);

struct pfm_observer* manifest_verification_get_pfm_observer (
	struct manifest_verification *verification);
struct cfm_observer* manifest_verification_get_cfm_observer (
	struct manifest_verification *verification);
struct pcd_observer* manifest_verification_get_pcd_observer (
	struct manifest_verification *verification);


#define	MANIFEST_VERIFICATION_ERROR(code)		ROT_ERROR (ROT_MODULE_MANIFEST_VERIFICATION, code)

/**
 * Error codes that can be generated by manifest verification.
 */
enum {
	MANIFEST_VERIFICATION_INVALID_ARGUMENT = MANIFEST_VERIFICATION_ERROR (0x00),	/**< Input parameter is null or not valid. */
	MANIFEST_VERIFICATION_NO_MEMORY = MANIFEST_VERIFICATION_ERROR (0x01),			/**< Memory allocation failed. */
};


#endif /* MANIFEST_VERIFICATION_H_ */
